package com.bms.client.service.impl;

import com.bms.client.utils.MyPublisher;
import com.bms.client.mapper.*;
import com.bms.client.pojo.*;
import com.bms.client.service.ChuFangGuanLiService;
import com.bms.client.service.FeiYongGuanLiService;
import com.bms.client.service.LaiFangGuanLiService;
import com.bms.client.utils.RedisUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 费用管理(FeiYongGuanLi)表服务实现类
 *
 * @author makejava
 * @since 2021-03-16 11:25:10
 * @version 1.0
 */
@Service("feiYongGuanLiService")
public class FeiYongGuanLiServiceImpl implements FeiYongGuanLiService {
    @Resource
    private FeiYongGuanLiMapper feiYongGuanLiMapper;
    @Resource
    private ChuFangGuanLiMapper chuFangGuanLiMapper;
    @Resource
    private LaiFangGuanLiMapper laiFangGuanLiMapper;
    @Resource
    private LaiFangGuanLiService laiFangGuanLiService;
    @Resource
    private ChuFangGuanLiService chuFangGuanLiService;
    @Resource
    private RedisUtils redisUtils;
    @Resource
    private HeZuoJiHuaGuanLiMapper heZuoJiHuaGuanLiMapper;
    @Resource
    private XiangMuMapper xiangMuMapper;
    @Resource
    private KeYanRenYuanMapper keYanRenYuanMapper;
    @Resource
    private MyPublisher publisher;
    /**
     * 根据模糊条件查询总个数
     *
     * @return 返回查询到的总个数
     */
	@Override
    public Map<String, Object> chaXunCount(FeiYongGuanLiChanXun feiYongGuanLiChanXun) {
        Map<String, Object> map = new HashMap<>();
        // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
        map.put("code", 200);
        map.put("msg", "查询成功");
        map.put("list", this.feiYongGuanLiMapper.chaXunCount(feiYongGuanLiChanXun));
        return map;
    }

    /**
     * 查询所有数据
     * @return  返回所有数据
     */
	@Override
    public Map<String, Object> chaXunAll() {
        Map<String, Object> map = new HashMap<>();
        // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
        map.put("code", 200);
        map.put("msg", "查询成功");
        map.put("list", this.feiYongGuanLiMapper.chaXunAll());
        return map;
    }

    /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
	@Override
    public Map<String, Object> chaXunById(Integer id) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", 200);
        map.put("msg", "查询成功");
        map.put("obj",feiYongGuanLiMapper.chaXunById(id));
        return map;
    }

    /**
     * 查询分页数据
     *
     * chanXunFenYei
     * @return 对象列表
     */
	@Override
    public Map<String, Object> chaXunFenYe(FeiYongGuanLiChanXun feiYongGuanLiChanXun) {
    // 获取当前表中的总记录
        int tableCount = this.feiYongGuanLiMapper.chaXunCount(feiYongGuanLiChanXun);
        // 总页码计算   (总条数 - 1) / 每页显示条数  + 1
        // (100 - 1) / 10 + 1 = 10        (101 - 1) / 10 + 1 = 11      (99 - 1) / 10 + 1 = 10
        int pageCount = (tableCount - 1) / 10 + 1;
        // 计算每页开始的下标值
        feiYongGuanLiChanXun.setPage((feiYongGuanLiChanXun.getPage() - 1) * 10);
        Map<String, Object> map = new HashMap<>();
        map.put("code", 0);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
        map.put("msg", "查询成功");
        map.put("pageCount", pageCount);  // 查询的记录总页码
        map.put("count", tableCount);     // 当前表中的总条数
        map.put("data", this.feiYongGuanLiMapper.chaXunFenYe(feiYongGuanLiChanXun));
        return map;
    }

    /**
     * 新增数据
     *
     * @param feiYongGuanLiZhengJia 实例对象
     * @return 实例对象
     */
	@Override
    @Transactional(rollbackFor = Throwable.class)
    public Map<String, Object> xinZengXiangMuJingFei(FeiYongGuanLiZhengJia feiYongGuanLiZhengJia) {
        Map<String, Object> map = new HashMap<>();
	    FeiYongGuanLi feiYongGuanLi=new FeiYongGuanLi();
        BeanUtils.copyProperties(feiYongGuanLiZhengJia,feiYongGuanLi);
        if(keYanRenYuanMapper.chaXunById(feiYongGuanLiZhengJia.getKeYanRenYuanId())==null){
            map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
            map.put("msg", "新增失败，该科研人员不存在");
            return map;
        }
        if(xiangMuMapper.chaXunById(feiYongGuanLiZhengJia.getGaunLianId())==null){
            map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
            map.put("msg", "新增失败，该项目不存在");
            return map;
        }
        feiYongGuanLi.setXangWei("项目");
        feiYongGuanLi.setZhuangTai("审核中");
        feiYongGuanLi.setBoKuanZhuangTai("未拨款");
        feiYongGuanLi.setShiJian(new Date(System.currentTimeMillis()));
        this.feiYongGuanLiMapper.xinZeng(feiYongGuanLi);

        redis(feiYongGuanLi.getId(),0);


        map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
        map.put("msg", "新增成功");
        return map;
    }

    /**
     * 通过ID查询单条数据
     *
     * @param feiYongGuanLi 实例对象
     * @return 实例对象
     */
	@Override
    @Transactional(rollbackFor = Throwable.class)
    public Map<String, Object> gengXinById(FeiYongGuanLi feiYongGuanLi) {
        Map<String, Object> map = new HashMap<>();
	    if(feiYongGuanLiMapper.chaXunById(feiYongGuanLi.getId())==null){
            map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
            map.put("msg", "该费用信息不存在");
            return map;
        }
        this.feiYongGuanLiMapper.gengXinById(feiYongGuanLi);

	    redis(feiYongGuanLi.getId(),1);

        map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
        map.put("msg", "更新成功");
        return map;
    }

    /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 是否成功
     */
	@Override
    @Transactional(rollbackFor = Throwable.class)
    public Map<String, Object> shanChuById(int id) {
        Map<String, Object> map = new HashMap<>();
        this.feiYongGuanLiMapper.shanChuById(String.valueOf(id));

	    if(!redisUtils.redisDelete("feiYongGuanLi",String.valueOf(id))){
            map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
            map.put("msg", "请不要重复删除");
            return map;
        }
        map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
        map.put("msg", "删除成功");
        return map;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Map<String, Object> xinZengHeZuoJingFei(FeiYongGuanLiZhengJia feiYongGuanLiZhengJia) {
        Map<String, Object> map = new HashMap<>();
        if(keYanRenYuanMapper.chaXunById(feiYongGuanLiZhengJia.getKeYanRenYuanId())==null){
            map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
            map.put("msg", "新增失败，该科研人员不存在");
            return map;
        }
        if(heZuoJiHuaGuanLiMapper.chaXunById(feiYongGuanLiZhengJia.getGaunLianId())==null){
            map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
            map.put("msg", "新增失败该合作项目不存在");
            return map;
        }
        FeiYongGuanLi feiYongGuanLi=new FeiYongGuanLi();
        BeanUtils.copyProperties(feiYongGuanLiZhengJia,feiYongGuanLi);
        feiYongGuanLi.setXangWei("合作");
        feiYongGuanLi.setZhuangTai("审核中");
        feiYongGuanLi.setBoKuanZhuangTai("未拨款");
        feiYongGuanLi.setShiJian(new Date(System.currentTimeMillis()));
        this.feiYongGuanLiMapper.xinZeng(feiYongGuanLi);

        redis(feiYongGuanLi.getId(),0);

        map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
        map.put("msg", "新增成功");
        KeYanRenYuan keYanRenYuan = keYanRenYuanMapper.chaXunById(feiYongGuanLiZhengJia.getKeYanRenYuanId());
        String name="";
        if(keYanRenYuan!=null){
            name=keYanRenYuan.getMingCheng();
        }
        publisher.sendMessage("您有待审核的合作计划经费，申请人为"+name);
        return map;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Map<String, Object> gengXinShenHeById(int id, String zhuangTai, String guanLiYuanPiZhu) {
        Map<String, Object> map = new HashMap<>();
        if(guanLiYuanPiZhu!=null&&guanLiYuanPiZhu.length()>25){
            map.put("code", 415);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
            map.put("msg", "管理员批注小于25的字符");
            return map;
        }
	    if("已审核".equals(zhuangTai)||"未审核".equals(zhuangTai)||"审核中".equals(zhuangTai)){
            FeiYongGuanLi feiYongGuanLi=new FeiYongGuanLi();
            feiYongGuanLi.setId(id);
            feiYongGuanLi.setZhuangTai(zhuangTai);
            feiYongGuanLi.setGuanLiYuanPiZhu(guanLiYuanPiZhu);
            feiYongGuanLi.setShiJian(new Date(System.currentTimeMillis()));
            feiYongGuanLiMapper.gengXinById(feiYongGuanLi);

            redis(id,1);
            map.put("code", 200);
            map.put("msg", "状态更新成功");
            return map;
        }


        map.put("code", 415);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
        map.put("msg", "状态是（已审核，未审核，审核中）");
        return map;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Map<String, Object> gengXinBoKuanById(int id, String boKuanZhuangTai, String guanLiYuanPiZhu) {
        Map<String, Object> map = new HashMap<>();
        if(guanLiYuanPiZhu.length()>25){
            map.put("code", 415);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
            map.put("msg", "管理员批注小于25的字符");
            return map;
        }
        if("已拨款".equals(boKuanZhuangTai)||"未拨款".equals(boKuanZhuangTai)){
            FeiYongGuanLi feiYongGuanLi=new FeiYongGuanLi();
            if(!"已审核".equals(feiYongGuanLiMapper.chaXunById(id).getZhuangTai())){
                map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
                map.put("msg", "审核未通过，请审核");
                return map;
            }
            feiYongGuanLi.setShiJian(new Date(System.currentTimeMillis()));
            feiYongGuanLi.setId(id);
            feiYongGuanLi.setBoKuanZhuangTai(boKuanZhuangTai);
            feiYongGuanLi.setGuanLiYuanPiZhu(guanLiYuanPiZhu);
            feiYongGuanLiMapper.gengXinById(feiYongGuanLi);

            redis(id,1);

            map.put("code", 200);
            map.put("msg", "更新成功");
            return map;
        }
        map.put("code", 200);
        map.put("msg", "拨款状态不满足格式（已拨款，未拨款）");
        return map;
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Map<String, Object> xinZengChuLaiJingFei(String zhuangTai,FeiYongGuanLiZhengJia feiYongGuanLiZhengJia) {
         int id = feiYongGuanLiZhengJia.getGaunLianId();
        Map<String, Object> map = new HashMap<>();
        if("出访".equals(zhuangTai)){
            ChuFangGuanLi chuFangGuanLi = chuFangGuanLiMapper.chaXunById(id);
            if(chuFangGuanLi==null||chuFangGuanLi.getHeZuoJiHuaId()==-1){
                map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
                map.put("msg", "该出访记录关联的合作数据,无法申请经费");
                return map;
            }
            if(chuFangGuanLi.getFeiYongId()!=null){
                map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
                map.put("msg", "已申请经费，请勿重复申请");
                return map;
            }
            FeiYongGuanLi feiYongGuanLi=new FeiYongGuanLi();
            BeanUtils.copyProperties(feiYongGuanLiZhengJia,feiYongGuanLi);
            feiYongGuanLi.setXangWei("出访");
            feiYongGuanLi.setZhuangTai("审核中");
            feiYongGuanLi.setBoKuanZhuangTai("未拨款");
            feiYongGuanLi.setShiJian(new Date(System.currentTimeMillis()));
            this.feiYongGuanLiMapper.xinZeng(feiYongGuanLi);

            redis(feiYongGuanLi.getId(),0);

            chuFangGuanLiMapper.gengXinFeiYongById(String.valueOf(id),feiYongGuanLi.getId().toString());

            chuFangGuanLiService.redis(id,1);

            KeYanRenYuan keYanRenYuan = keYanRenYuanMapper.chaXunById(feiYongGuanLiZhengJia.getKeYanRenYuanId());
            String name="";
            if(keYanRenYuan!=null){
                name=keYanRenYuan.getMingCheng();
            }
            publisher.sendMessage("您有待审核的出访计划经费，申请人为"+name);
        }else if("来访".equals(zhuangTai)){
            LaiFangGuanLi laiFangGuanLi = laiFangGuanLiMapper.chaXunById(id);
            if(laiFangGuanLi==null||laiFangGuanLi.getHeZuoJiHuaId()==-1){
                map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
                map.put("msg", "该来访记录关联的合作数据,无法申请经费");
                return map;
            }
            if(laiFangGuanLi.getFeiYong()>0){
                map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
                map.put("msg", "已申请经费，请勿重复申请");
                return map;
            }
            FeiYongGuanLi feiYongGuanLi=new FeiYongGuanLi();
            BeanUtils.copyProperties(feiYongGuanLiZhengJia,feiYongGuanLi);
            feiYongGuanLi.setXangWei("来访");
            feiYongGuanLi.setZhuangTai("审核中");
            feiYongGuanLi.setBoKuanZhuangTai("未拨款");
            feiYongGuanLi.setShiJian(new Date(System.currentTimeMillis()));
            this.feiYongGuanLiMapper.xinZeng(feiYongGuanLi);

            redis(feiYongGuanLi.getId(),0);

            laiFangGuanLiMapper.gengXinFeiYongById(String.valueOf(id),feiYongGuanLi.getId());

            laiFangGuanLiService.redis(id,1);
            KeYanRenYuan keYanRenYuan = keYanRenYuanMapper.chaXunById(feiYongGuanLiZhengJia.getKeYanRenYuanId());
            String name="";
            if(keYanRenYuan!=null){
                name=keYanRenYuan.getMingCheng();
            }
            publisher.sendMessage("您有待审核的来访计划经费，申请人为"+name);

        }else {
            map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
            map.put("msg", "请传入正确的状态信息(出访或来访)");
            return map;
        }
        map.put("code", 200);   // 前端端分离时，前端人员会首先判断code值是否满足200，如果不是200，则提醒用户失败
        map.put("msg", "添加成功");
        return map;
    }

    private void redis(int id,int stat){
        FeiYongGuanLi myFeiYongGuanLi =(FeiYongGuanLi) chaXunById(id).get("obj");
        if(myFeiYongGuanLi!=null){
            Map<String,String> conditionalQueue=new HashMap<>();
            conditionalQueue.put("keYanRenYuanXingMing",myFeiYongGuanLi.getKeYanRenYuan().getMingCheng());
            conditionalQueue.put("zhuangTai",myFeiYongGuanLi.getZhuangTai());
            conditionalQueue.put("boKuanZhuangTai",myFeiYongGuanLi.getBoKuanZhuangTai());
            conditionalQueue.put("xangWei",myFeiYongGuanLi.getXangWei());
            conditionalQueue.put("gaunLianId",myFeiYongGuanLi.getGaunLianId().toString());
            if(stat==1){
                redisUtils.redisUpData("feiYongGuanLi",conditionalQueue,myFeiYongGuanLi.getId().toString(),myFeiYongGuanLi);
            }
            if(stat==0){
                redisUtils.redisInsert("feiYongGuanLi",conditionalQueue,myFeiYongGuanLi.getId().toString(),myFeiYongGuanLi);
            }
        }
        }
}